<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js">;(function(){
	// ------Class Creation------
    var initializing = false,
	fnTest = /xyz/.test(function() {
	    xyz;
	}) ? /\b_super\b/: /.*/;
	var OPTS_NAME = 'OPTS';
	var debug = false;
	// The base Class implementation (does nothing)
	this.Class = function() {};
	
	// Create a new Class that inherits from this class
	Class.extend = function(className,prop) {
	    var _super = this.prototype;
	
	    // Instantiate a base class (but only create the instance,
	    // don't run the init constructor)
	    initializing = true;
	    var prototype = new this();
	    initializing = false;
	
	    // Copy the properties over onto the new prototype
	    for (var name in prop) {
	    	
	    	var newPropVal = null; 
	    	// 如果子类重写父类的方法
	    	if(typeof prop[name] == &quot;function&quot; &amp;&amp; typeof _super[name] == &quot;function&quot; &amp;&amp; fnTest.test(prop[name])) {
	    		newPropVal = (function(name, fn) {
					return function() {
		                var tmp = this._super;
		
		                // Add a new ._super() method that is the same method
		                // but on the super-class
		                this._super = _super[name];
		
		                // The method only need to be bound temporarily, so we
		                // remove it when we're done executing
		                var ret = fn.apply(this, arguments);
		                this._super = tmp;
		
		                return ret;
		            };
				})(name, prop[name]);
	    	}else if(typeof prop[name] == &quot;function&quot;) { // 如果子类没有重写父类的方法,即新方法
	    		newPropVal = prop[name];
	    	}else if(name == OPTS_NAME) { // 如果是特定的属性对象
	    		// 拷贝对象
	    		var ret = {};
				var o = _super[name] || {};
				for(var p in o) {
					ret[p] = o[p];
				}
				
				var c = prop[name];
		        for(var p in c) {
		            ret[p] = c[p];
		        }
		        
		        newPropVal = ret;
	    	}else {
	    		newPropVal = prop[name];
	    	}
	    	
	    	prototype[name] = newPropVal;
	    }
	
	    // The dummy class constructor
	    function Class() {
	        // All construction is actually done in the init method
	        if (!initializing &amp;&amp; this.init) {
	        	if(debug) {
	        		try{
			        	this.init.apply(this, arguments);
		        	}catch(e) {
		        		console.error(e);
		        	}
	        	}else{
	        		this.init.apply(this, arguments);
	        	}
	        }
	    }
	
	    // Populate our constructed prototype object
	    Class.prototype = prototype;
	
	    // Enforce the constructor to be what we expect
	    Class.prototype.constructor = Class;
	
	    // And make this class extendable
	    Class.extend = arguments.callee;
	    
	    // ------自定义方法------
	    // 返回类名
	    prototype.getClassName = function() {
	    	return className;
	    }
	
		// ------自定义方法------
	    /* 接口检查,参数可以是一个或多个,使用方法:
		 * //声明接口
		 * var Interface1 = Class.createInterface(['getName']);
		 * // Person类实现接口
		 * var Person = Class.extend({...}).impl(Interface1);
		 */
	    Class.impl = function() {
	        if (arguments.length &gt; 0) {
	        	var _className = prototype.getClassName();
	            for (var i = 0, len = arguments.length; i &lt; len; i++) {
	                var interfac = arguments[i];
	                if (!interfac._isInterfaceType) {
	                    throw new Error(_className + &quot;.impl()第&quot; + (i + 1) + &quot;个参数必须是接口类型&quot;);
	                }
	                for (var j = 0, methodLen = interfac.methods.length; j &lt; methodLen; j++) {
	                    var method = interfac.methods[j];
	                    if (!prototype[method] || typeof prototype[method] !== &quot;function&quot;) {
	                        throw new Error(&quot;类&quot;+_className+&quot;没有实现接口中的[&quot; + method + &quot;]方法&quot;);
	                    }
	                }
	            }
	        }
	
	        return Class;
	    };// ------自定义方法 end------
	
	    return Class;
	};// ------Class Creation end------
	
	// 辅助类
	var Interface = function(_methods) {
		if (arguments.length != 1) {
			throw new Error(&quot;创建接口参数只能有一个,并且为数组类型&quot;);
		}
		this.methods = [];
		this._isInterfaceType = true;

		for (var i = 0, len = _methods.length; i &lt; len; i++) {
			if (typeof _methods[i] !== &quot;string&quot;) {
				throw new Error(&quot;定义接口中的方法必须为字符串类型&quot;);
			}
			this.methods.push(_methods[i]);
		}
	}
	
	var id = 0;

	var VUI =  {
		copy:function(o, c) {
			if(o &amp;&amp; c &amp;&amp; typeof c == 'object') {
		        for(var p in c) {
		            o[p] = c[p];
		        }
		    }
		    return o;
		}
		,copyNew:function(o, c) {
			var ret = {};
			if(o &amp;&amp; c &amp;&amp; typeof c == 'object') {
				
				for(var p in o) {
					ret[p] = o[p];
				}
				
		        for(var p in c) {
		            ret[p] = c[p];
		        }
		    }
		    return ret;
		}
<span id='global-method-Interface'>		/**
</span>		 * 创建接口
		 * @param {String} className 类名
		 * @param {Array} methods 接口方法列表
		 */
		,Interface:function(className,methods) {
			var _interface = new Interface(methods);
			_interface.className = className;
			this[className] = _interface;
			return _interface;
		}
<span id='global-method-Class'>		/**
</span>		 * 创建类
		 * @param {String} className 类名
		 * @param {Object} props 类方法
		 * @param {Function} superClass 父类
		 */
		,Class:function(className,props,superClass) {
			superClass = superClass || Class;
			
			var Clazz = superClass.extend(className,props);
			
			this[className] = Clazz;
			
			return Clazz;
		}
<span id='global-method-format'>		/**
</span>		 * 格式化字符串
		 * @example 用法:
		 * VUI.format('{y}年{m}月{d}日',{y:'2010',m:'09',d:'15'});
		 * 返回:2010年09月15日
		 * 
		 * @param str 需要格式化的字符串
		 * @param obj json数据
		 * @return 返回格式化后的字符串
		 */
		,format:function(str,obj){
			for(var key in obj){
				str = str.replace(new RegExp(&quot;\\{\\s*&quot; + key + &quot;\\s*\\}&quot;, &quot;g&quot;), obj[key]);
			}
			return str;
		}
		,log:function(s) {
			if(window.console) {
				this.log = function(s) {
					console.log(s);
				}
			}
			this.log(s);
		}
<span id='global-method-getId'>		/**
</span>		 * 获取唯一ID
		 */
		,getId:function() {
			return id++;
		}
	}
	
	window.VUI = VUI.copy(window.VUI || {},VUI);
	
})();</pre>
</body>
</html>
